package ctp.trade;

import ctp.thostapi.*;

import static ctp.thostapi.thosttraderapiConstants.*;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import java.util.*;


/**
 * 自定义TradeApi类，实现认证、登陆、结算单确认、报单录入、撤单等功能
 */
public class MyTradeApi {


    private static final Properties properties = new Properties();
    private static FileReader fr;
    private static ArrayList<Character> OrderPriceTypeList = new ArrayList<Character>();
    private static ArrayList<Character> DirectionList = new ArrayList<Character>();


    static {
        OrderPriceTypeList.add(THOST_FTDC_OPT_LimitPrice);  //限价单
        OrderPriceTypeList.add(THOST_FTDC_OPT_AnyPrice);    //市价单

        DirectionList.add(THOST_FTDC_D_Buy);  //买
        DirectionList.add(THOST_FTDC_D_Sell);    //卖

        try {
            fr = new FileReader("./config/config.ini");
        } catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        }
        try {
            properties.load(fr);
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        try {
            fr.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    private String m_TFrontAddr = properties.getProperty("tradefront");
    private String m_BrokerId = properties.getProperty("brokerid");
    private String m_UserId = properties.getProperty("userid");
    private String m_InvestorId = properties.getProperty("userid");
    private String m_PassWord = properties.getProperty("password");
    private String m_AccountId = properties.getProperty("userid");
    private String m_AppId = properties.getProperty("appid");
    private String m_AuthCode = properties.getProperty("authcode");
    private String m_InstrumentID = properties.getProperty("instrid");
    private String m_OrderPriceType = properties.getProperty("pricetype");
    private String m_Direction = properties.getProperty("dir");
    private String m_CombOffsetFlag = properties.getProperty("offset");
    private String m_CombHedgeFlag = properties.getProperty("hedge");
    private String m_LimitPrice = properties.getProperty("price");
    private String m_VolumeTotalOriginal = properties.getProperty("volume");

    private CThostFtdcTraderApi traderApi;


    /**
     * 初始化函数
     */
    public void start() {
        traderApi = CThostFtdcTraderApi.CreateFtdcTraderApi();
        // System.out.println(traderApi.GetApiVersion());
        MyTradeSpi traderSpi = new MyTradeSpi(this);
        traderApi.RegisterSpi(traderSpi);
        traderApi.RegisterFront(m_TFrontAddr);
        traderApi.SubscribePublicTopic(THOST_TE_RESUME_TYPE.THOST_TERT_QUICK);
        traderApi.SubscribePrivateTopic(THOST_TE_RESUME_TYPE.THOST_TERT_QUICK);
        traderApi.Init();
    }

    /**
     * 客户端等待一个接口实例线程的结束。
     */
    public void join() {
        traderApi.Join();
    }

    /**
     * 认证函数
     */
    public void ReqAuthenticate() {
        CThostFtdcReqAuthenticateField field = new CThostFtdcReqAuthenticateField();
        field.setBrokerID(m_BrokerId);
        field.setUserID(m_UserId);
        field.setAppID(m_AppId);
        field.setAuthCode(m_AuthCode);
        traderApi.ReqAuthenticate(field, 0);
        System.out.println("Send ReqAuthenticate ok");
    }

    /**
     * 登陆函数
     */
    public void ReqUserLogin() {
        CThostFtdcReqUserLoginField field = new CThostFtdcReqUserLoginField();
        field.setBrokerID(m_BrokerId);
        field.setUserID(m_UserId);
        field.setPassword(m_PassWord);
        traderApi.ReqUserLogin(field, 0);
        System.out.println("Send login ok");

    }

    /**
     * 结算单确认函数
     */
    public void ReqSettlementInfoConfirm() {
        CThostFtdcSettlementInfoConfirmField field = new CThostFtdcSettlementInfoConfirmField();
        field.setBrokerID(m_BrokerId);
        field.setInvestorID(m_InvestorId);
        traderApi.ReqSettlementInfoConfirm(field, 0);
        System.out.println("Send settlement info confirm ok");
    }

    /**
     * 报单录入函数
     */
    public void ReqOrderInsert() {
        CThostFtdcInputOrderField field = new CThostFtdcInputOrderField();
        field.setBrokerID(m_BrokerId);
        field.setInvestorID(m_InvestorId);
        field.setInstrumentID(m_InstrumentID);
        // field.setOrderRef('001');   // 可自定义或不填
        field.setOrderPriceType(OrderPriceTypeList.get(Integer.parseInt(m_OrderPriceType)));
        field.setDirection(DirectionList.get(Integer.parseInt(m_Direction)));
        field.setCombOffsetFlag(m_CombOffsetFlag);
        field.setCombHedgeFlag(m_CombHedgeFlag);
        field.setLimitPrice(Double.parseDouble(m_LimitPrice));
        field.setVolumeTotalOriginal(Integer.parseInt(m_VolumeTotalOriginal));
        field.setTimeCondition(THOST_FTDC_TC_GFD);  ///当日有效
        field.setVolumeCondition(THOST_FTDC_VC_AV); ///任意数量
        field.setContingentCondition(THOST_FTDC_CC_Immediately);
        field.setForceCloseReason(THOST_FTDC_FCC_NotForceClose);
        field.setIsAutoSuspend(0);  //必填0
        field.setIsSwapOrder(0);    //互换单填1
        // field.setUserForceClose(0);  //用户强平标志
        traderApi.ReqOrderInsert(field, 0);
        System.out.println("Send order insert ok");
    }

    /**
     * 撤单函数
     */
    public void ReqOrderDelete(String ExchangeID, String OrderSysID) {
        StringBuilder m_OrderSysID = new StringBuilder();
        if (OrderSysID.length() > 12) {
            System.out.println("OrderSysID too length > 12");
            return;
        }
        else if (OrderSysID.length() < 12){
            char[] chars = new char[12 - OrderSysID.length()];
            Arrays.fill(chars, ' ');
            m_OrderSysID.append(new String(chars));
            m_OrderSysID.append(OrderSysID);
        }
        else {
            m_OrderSysID.append(OrderSysID);
        }
        CThostFtdcInputOrderActionField field = new CThostFtdcInputOrderActionField();
        field.setBrokerID(m_BrokerId);
        field.setInvestorID(m_InvestorId);
        field.setUserID(m_UserId);
        field.setInstrumentID(m_InstrumentID);
        field.setExchangeID(ExchangeID);
        field.setActionFlag(THOST_FTDC_AF_Delete);
        field.setOrderSysID(m_OrderSysID.toString());
        traderApi.ReqOrderAction(field, 0);
        System.out.println("Send order delete ok");
    }
}
